/*
********************************************************************************
* Copyright (C) 2021, xiang.D <dx_65535@163.com>.
* All right reserved.
*
* File Name   : led_factory.cc
* Author      :
* Version     : V1.0
* Description :
* Journal     : 2021-01-15 init v1.0
* Brief       : Blog: https://blog.csdn.net/qq_38750572?spm=1001.2014.3001.5343
* Others      :
********************************************************************************
*/
#include "led_factory.h"

#define FACTORY_LOGD(fmt, args...)
#define FACTORY_LOGI(fmt, args...) printf("%d LedFactory I: " fmt, __LINE__, ##args)
#define FACTORY_LOGW(fmt, args...) printf("%d LedFactory W: " fmt, __LINE__, ##args)
#define FACTORY_LOGE(fmt, args...) printf("%d LedFactory E: " fmt, __LINE__, ##args)
#define FACTORY_LOG(fmt, args...)  printf(fmt, ##args)


CLedFactory* CLedFactory::GetInstance()
{
    static CLedFactory obj;
    return &obj;
}

CLed* CLedFactory::GetLed(EPermission permission, EUsedMode mode, int freq)
{
    int i, sum = 0, location = -1;

    switch (permission)
    {
        case LED_UNSHARED:
        {
            // 返回Power Led对象
            if (CUnsharedLed::GetInstance()->GetStatus() == LED_IDLE) {
                CUnsharedLed::GetInstance()->SetStatus(LED_BUSY);
                return CUnsharedLed::GetInstance();
            } else {
                return NULL;
            }
        }
        break;

        case LED_SHARED:
        {
            sum = mLedTable.size();
            // loop: 遍历所有LED状态，返回空闲的LED
            for (i = 0; i < sum; i++) {
                if ( mLedTable[i]->GetStatus() == LED_IDLE)
                {
                    location = i;
                    goto RET;       // 找到空闲的LED， 返回当前下标
                }
            }

            // 当前存在的LED对象都处于busy状态，
            // 若Led资源未到上限，则创建新的Led对象。
            if (i == sum && sum < MAX_SHARED_LED) {
                FACTORY_LOGD("Create Shared Led %d!\n", i);
                mLedTable.insert(std::pair<int, CLed*>(i, new CSharedLed()));
                location = i;
            }
        }
        break;

        default:
        break;
    }

RET:
    if (location >= 0) {
        mLedTable[location]->UpdateLed(permission, mode, freq);
        return mLedTable[location];
    } else {
        return NULL;
    }
}
